#include "TriGrid.h"

TriGrid::TriGrid()
{
}

TriGrid::TriGrid(int width, int depth, float dx, float dz)
: mWidth(width)
, mDepth(depth)
, mTileWidth(dx)
, mTileDepth(dz)
{
	mNumVertices = (++width) * (++depth);
	mNumFaces = width * depth * 2;

	BuildVertexBuffer();
	BuildIndexBuffer();

	D3DXCreateEffectFromFile(gD3DDevice, "Transform.fx", 0, 0, D3DXSHADER_DEBUG, 0, &mFx, &mErrors);
	if (mErrors)
	{
		MessageBox(0, (char*)mErrors->GetBufferPointer(), 0, 0);
	}

	mhTech = mFx->GetTechniqueByName("WaveTech");
	mhWVP = mFx->GetParameterByName(0, "gWVP");
	mhTime = mFx->GetParameterByName(0, "gTime");

	mFx->SetTechnique(mhTech);
}

TriGrid::~TriGrid()
{

}

void TriGrid::Update(double dt)
{
	mFx->SetFloat(mhTime, gTimer->GetGameTime());
}

void TriGrid::Draw(ID3DXSprite& sprite, D3DXMATRIX& view, D3DXMATRIX& proj)
{
	HR(gD3DDevice->SetStreamSource(0, mVB, 0, sizeof(VertexPosCol)));
	HR(gD3DDevice->SetVertexDeclaration(VertexPosCol::decl));
	HR(gD3DDevice->SetIndices(mIB));

	D3DXMATRIX world;
	D3DXMatrixIdentity(&world);
	mFx->SetMatrix(mhWVP, &(world * view * proj));

	UINT numPasses = 0;
	mFx->Begin(&numPasses, 0);
	for (UINT i = 0; i < numPasses; i++)
	{
		mFx->BeginPass(i);
		HR(gD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mNumVertices, 0, mNumFaces));
		mFx->EndPass();
	}
	mFx->End();
}

void TriGrid::BuildVertexBuffer()
{
	HR(gD3DDevice->CreateVertexBuffer(mNumVertices * sizeof(VertexPosCol),
		D3DUSAGE_WRITEONLY,
		0, D3DPOOL_MANAGED,
		&mVB, 0));

	VertexPosCol* vertices = 0;
	HR(mVB->Lock(0, 0, (void**)&vertices, 0));

	float halfWidth = (mWidth - 1) * mTileWidth * 0.5f;
	float halfDepth = (mDepth - 1) * mTileDepth * 0.5f;
	for (unsigned int i = 0; i < mWidth; ++i)
	{
		float z = halfDepth - i * mTileWidth;
		for (unsigned int j = 0; j < mDepth; ++j)
		{
			float x = -halfWidth + j * mTileWidth;
			float y = 0.0f;

			vertices[i * mDepth + j].pos = D3DXVECTOR3(x, y, z);
			vertices[i * mDepth + j].col = D3DCOLOR_XRGB(255, 0, 0);
		}
	}

	HR(mVB->Unlock());
}

void TriGrid::BuildIndexBuffer()
{
	HR(gD3DDevice->CreateIndexBuffer((mWidth * 6) * (mDepth * 6) * sizeof(WORD),
		D3DUSAGE_WRITEONLY,	D3DFMT_INDEX32, 
		D3DPOOL_MANAGED, &mIB, 0));

	DWORD* indices = 0;
	HR(mIB->Lock(0, 0, (void**)&indices, 0));

	int k = 0;
	for (unsigned int i = 0; i < mWidth-1; ++i)
	{
		for (unsigned int j = 0; j < mDepth-1; ++j)
		{
			indices[k + 0] = i * mDepth + j;
			indices[k + 1] = i * mDepth + (j + 1);
			indices[k + 2] = (i + 1) * mDepth + j;
			indices[k + 3] = (i + 1) * mDepth + j;
			indices[k + 4] = i * mDepth + (j + 1);
			indices[k + 5] = (i + 1) * mDepth + (j + 1);
			k += 6;
		}
	}

	HR(mIB->Unlock());
}
